package test.shutdown;

import org.junit.jupiter.api.Test;



/**
 * @category 向上向下转型精简化笔记
 * 			通俗理解方式
 *
 */
public class 简单理解向上向下转型 {						//测试类，看看大家的能力如何
	public static void main(String[] args) {
		Father father = new Father();	//正常定义父类
		Son son = new Son();		//正常定义子类
		Father dadTs = new Son();	//自动向上转型，长大成为爸爸
		//Son kidTs = new Father();	//强制向下转型失败，爸爸不能再次变回儿子(标红线，代表没有这种写法)
		
		//下面看看大家能力都有什么
		father.ability();
		father.power();
		father.power1();
		//father.play();	//父类不能使用子类特有的方法
		//father可以调用自己的所有方法
		son.ability();
		son.power();
		son.property();
		son.power1();
		son.property();
		son.play();
		//son可以调用自己的，包括从父类继承过来的所有方法
		dadTs.ability();
		dadTs.power();
		dadTs.power1();
		dadTs.property();
		//dadTs.play();//自动向上转型的不能使用子类方法
		
//		((Father)null).power1();
//		((Father)null).power();
		
	//================================================================================================================================================================	
		//有趣的内容：
		//定义了一个A类型的a，赋了一个B对象，使用a.get方法。
		// 程序执行，由于是A类型，所以会去A里面找，找到了，是get(A a),但是参数是b对象，所以去B里找，由于已经确定了是get(A a),所以在B中找到的是get(A a)而不是get(B b),所以B里的get(A a)执行了。
		// 由于a1是A类型，所以回去A里面找，找到了，是get(A a),但是参数是c对象，所以去C里面找，由于已经确定了是get(A a),C中没找到，就去C的父类中找，找到了get(A a),就执行了
		// 总结：对象调用方法时，会根据变量类型、所赋值的类型动态查找方法执行【先找方法表方发表，再看指向的对象】
		System.out.println("================");
		
		A a = new B();
		A a1 = new C();

		a.get(new C());
		a.get(new B());
		a.get(new A());
		System.out.println("================");
		a1.get(new C());
		a1.get(new B());
		a1.get(new A());
	}
}

class A{
																									//区域C：LINE:36-77
	public void get(A a) {
		System.out.println("A...A");
	}
}

class B extends A{
	public void get(A a) {
		System.out.println("B...A");
	}
	
	public void get(B b) {
		System.out.println("B...B");
	}
}

class C extends B{
	public void get(C c) {
		System.out.println("C....C");
	}
}
//================================================================================================================================================================


class Father{
	public void ability() {
		System.out.println("我是爸爸");
	}
	public void property() {
		System.out.println("我有很多财产");
	}
	public void power() {
		System.out.println("我会使用火遁秘法");
	}
	public static void power1() {
		System.out.println("我会使用火遁秘法");
	}
}
class Son extends Father{
	public void ability() {		//重写父类方法(能力转换)
		System.out.println("我是儿子");
	}
	public void power() {
		System.out.println("我会用火球术");
	}
	public static void power1() {
		System.out.println("我会法");
	}						//继承了"财产方法"
	public void play() {
		System.out.println("我喜欢玩过家家");
	}
}

class Magic{		//测试类，让父亲返老还童的魔法
		public static void main(String[] args) {
			//问题来了，如何让爸爸再次变回儿子呢？
			Father father = new Son();
			Son kid = (Son) father;	//使用秘术：返老还童！(用son的壳把father转换成son之后包起来)
									//由于father本质是父亲，所以即使返老还童最多也只能是一个kid
			//成功返老还童，但是年龄的减小会给父亲实力的减弱吗？
			kid.ability();
			kid.power();
			kid.power1();
			kid.property();
			kid.play();				//
						
			
	}
}